package com.demo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
 * 业务需求
 * 假如现在有20个人去售票厅买票，但是窗口只有2个，那么同时能够买票的只能有
 * 2个人，当2个人中任意一个人买好票离开之后，等待的18个人中又会有一个人可以占用窗口买票
 * 应用场景: 限流、如果资源访问需要控制(数据库连接、打印机接口)；
 * 连接数控制在一定的范围内，
 *
 */
public class SemaphoreDemo {
	/**
	 * 执行任务类，获取信号量和释放信号量
	 * @param args
	 */
	class SemaphoreRunnable implements Runnable{
		private Semaphore semaphore; //信号量
		private int user;//记录第几个用户
		
		public SemaphoreRunnable(Semaphore semaphore, int user) {
			super();
			this.semaphore = semaphore;
			this.user = user;
		}

		@Override
		public void run() {
			try {
				semaphore.acquire();//获取信号量许可
				System.out.println("用户[" + user+ "]进入窗口准备买票...");
				Thread.sleep( (long) (Math.random()*10000) );
				System.out.println("用户[" + user+ "]进入窗口买票完成...即将离开..");
				Thread.sleep( (long) (Math.random()*10000) );
				System.out.println("用户[" + user+ "]进入窗口买票完成...离开窗口..");
				semaphore.release();//释放信号量
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	private void  execute(){
		//定义窗口的个数
		final Semaphore semaphore = new Semaphore(2);
		//线程池
		ExecutorService threadPool=Executors.newCachedThreadPool();
		//模拟20个用户
		for(int i=0;i<20; i++){
			//去买票
			threadPool.execute(new SemaphoreRunnable(semaphore, i+1));
		}
		threadPool.shutdown();
	}
	public static void main(String[] args) {
		SemaphoreDemo semaphoreDemo=new SemaphoreDemo();
		semaphoreDemo.execute();

	}

}
